/**
 * 技能配置加载器
 * 负责从各种来源加载技能配置数据
 */

import { ModernSkill, SkillEffectConfig, SkillEffectType } from './SkillEffectTypes';
import { ServiceLogger } from '../../../../infrastructure/logging/UnifiedLogger';
import * as fs from 'fs/promises';
import * as path from 'path';

/**
 * 配置文件格式
 */
interface SkillConfigFile {
    version: string;
    skills: ModernSkill[];
    templates?: Record<string, Partial<ModernSkill>>;
    categories?: Record<string, string[]>;
}

/**
 * 技能配置加载器
 */
export class SkillConfigurationLoader {
    private logger: ServiceLogger;
    private configPath: string;
    private loadedSkills = new Map<string, ModernSkill>();
    private configTemplates = new Map<string, Partial<ModernSkill>>();

    constructor(configPath: string) {
        this.logger = new ServiceLogger('SkillConfigurationLoader');
        this.configPath = configPath;
    }

    /**
     * 加载所有技能配置
     */
    async loadAllSkills(): Promise<ModernSkill[]> {
        this.logger.info('Loading skill configurations...', {
            metadata: { configPath: this.configPath }
        });

        try {
            // 清空已加载的技能
            this.loadedSkills.clear();
            this.configTemplates.clear();

            // 查找所有配置文件
            const configFiles = await this.findConfigFiles();
            
            // 加载每个配置文件
            for (const filePath of configFiles) {
                await this.loadConfigFile(filePath);
            }

            // 应用模板和验证
            await this.processLoadedSkills();

            const skills = Array.from(this.loadedSkills.values());
            this.logger.info(`Successfully loaded ${skills.length} skills from ${configFiles.length} files`);
            
            return skills;

        } catch (error) {
            this.logger.error('Failed to load skill configurations', undefined, error);
            throw error;
        }
    }

    /**
     * 重新加载技能配置
     */
    async reloadSkills(): Promise<ModernSkill[]> {
        this.logger.info('Reloading skill configurations...');
        return await this.loadAllSkills();
    }

    /**
     * 加载单个技能
     */
    async loadSkill(skillId: string): Promise<ModernSkill | null> {
        // 如果已经加载过，直接返回
        if (this.loadedSkills.has(skillId)) {
            return this.loadedSkills.get(skillId)!;
        }

        // 尝试从配置文件中查找
        try {
            const configFiles = await this.findConfigFiles();
            
            for (const filePath of configFiles) {
                const config = await this.loadConfigFile(filePath);
                const skill = config.skills.find(s => s.id === skillId);
                if (skill) {
                    const processedSkill = await this.processSkill(skill);
                    this.loadedSkills.set(skillId, processedSkill);
                    return processedSkill;
                }
            }

            return null;
        } catch (error) {
            this.logger.error(`Failed to load skill: ${skillId}`, undefined, error);
            return null;
        }
    }

    /**
     * 验证技能配置
     */
    validateSkillConfig(skill: ModernSkill): { valid: boolean; errors: string[] } {
        const errors: string[] = [];

        // 基础字段验证
        if (!skill.id) errors.push('Missing skill ID');
        if (!skill.name) errors.push('Missing skill name');
        if (!skill.type) errors.push('Missing skill type');
        if (!skill.effects || skill.effects.length === 0) {
            errors.push('Missing skill effects');
        }

        // 效果配置验证
        if (skill.effects) {
            skill.effects.forEach((effect, index) => {
                const effectErrors = this.validateEffectConfig(effect, index);
                errors.push(...effectErrors);
            });
        }

        // 目标配置验证
        if (!skill.targeting) {
            errors.push('Missing targeting configuration');
        } else {
            if (typeof skill.targeting.targetCount !== 'number' && skill.targeting.targetCount !== 'all') {
                errors.push('Invalid target count');
            }
            if (!skill.targeting.targetType) {
                errors.push('Missing target type');
            }
        }

        // 冷却配置验证
        if (!skill.cooldown) {
            errors.push('Missing cooldown configuration');
        } else {
            if (typeof skill.cooldown.baseCooldown !== 'number' || skill.cooldown.baseCooldown < 0) {
                errors.push('Invalid base cooldown');
            }
        }

        return {
            valid: errors.length === 0,
            errors
        };
    }

    /**
     * 获取配置统计信息
     */
    getConfigStats(): {
        totalSkills: number;
        skillsByType: Record<string, number>;
        skillsByCategory: Record<string, number>;
        averageEffectsPerSkill: number;
        configFilesLoaded: number;
    } {
        const skills = Array.from(this.loadedSkills.values());
        const skillsByType: Record<string, number> = {};
        const skillsByCategory: Record<string, number> = {};
        let totalEffects = 0;

        for (const skill of skills) {
            // 统计技能类型
            skillsByType[skill.type] = (skillsByType[skill.type] || 0) + 1;
            
            // 统计技能分类
            skillsByCategory[skill.category] = (skillsByCategory[skill.category] || 0) + 1;
            
            // 统计效果数量
            totalEffects += skill.effects.length;
        }

        return {
            totalSkills: skills.length,
            skillsByType,
            skillsByCategory,
            averageEffectsPerSkill: skills.length > 0 ? totalEffects / skills.length : 0,
            configFilesLoaded: 0 // 这里需要跟踪已加载的文件数量
        };
    }

    // ==================== 私有方法 ====================

    /**
     * 查找配置文件
     */
    private async findConfigFiles(): Promise<string[]> {
        const configFiles: string[] = [];
        
        try {
            // 检查配置路径是否存在
            await fs.access(this.configPath);
            
            // 递归查找所有.json和.ts文件
            const files = await this.readDirectoryRecursive(this.configPath);
            
            for (const file of files) {
                if (file.endsWith('.json') || file.endsWith('.ts')) {
                    configFiles.push(file);
                }
            }
            
        } catch (error) {
            this.logger.warn(`Config path not accessible: ${this.configPath}`, undefined, error);
        }

        return configFiles;
    }

    /**
     * 递归读取目录
     */
    private async readDirectoryRecursive(dirPath: string): Promise<string[]> {
        const files: string[] = [];
        
        try {
            const entries = await fs.readdir(dirPath, { withFileTypes: true });
            
            for (const entry of entries) {
                const fullPath = path.join(dirPath, entry.name);
                
                if (entry.isDirectory()) {
                    const subFiles = await this.readDirectoryRecursive(fullPath);
                    files.push(...subFiles);
                } else {
                    files.push(fullPath);
                }
            }
        } catch (error) {
            this.logger.warn(`Failed to read directory: ${dirPath}`, undefined, error);
        }
        
        return files;
    }

    /**
     * 加载配置文件
     */
    private async loadConfigFile(filePath: string): Promise<SkillConfigFile> {
        try {
            const content = await fs.readFile(filePath, 'utf-8');
            
            let config: SkillConfigFile;
            
            if (filePath.endsWith('.json')) {
                config = JSON.parse(content);
            } else if (filePath.endsWith('.ts')) {
                // 对于TypeScript文件，我们需要动态导入
                const module = await import(filePath);
                config = module.default || module;
            } else {
                throw new Error(`Unsupported file format: ${filePath}`);
            }

            // 验证配置文件格式
            if (!config.skills || !Array.isArray(config.skills)) {
                throw new Error('Invalid config file format: missing skills array');
            }

            // 保存模板
            if (config.templates) {
                for (const [name, template] of Object.entries(config.templates)) {
                    this.configTemplates.set(name, template);
                }
            }

            this.logger.debug(`Loaded config file: ${filePath}`, {
                metadata: { 
                    skillCount: config.skills.length,
                    templateCount: Object.keys(config.templates || {}).length
                }
            });

            return config;

        } catch (error) {
            this.logger.error(`Failed to load config file: ${filePath}`, undefined, error);
            throw error;
        }
    }

    /**
     * 处理已加载的技能
     */
    private async processLoadedSkills(): Promise<void> {
        const skills = Array.from(this.loadedSkills.values());
        
        for (const skill of skills) {
            try {
                const processedSkill = await this.processSkill(skill);
                this.loadedSkills.set(skill.id, processedSkill);
            } catch (error) {
                this.logger.error(`Failed to process skill: ${skill.id}`, undefined, error);
            }
        }
    }

    /**
     * 处理单个技能
     */
    private async processSkill(skill: ModernSkill): Promise<ModernSkill> {
        // 应用模板
        let processedSkill = await this.applyTemplate(skill);
        
        // 设置默认值
        processedSkill = this.setDefaultValues(processedSkill);
        
        // 验证配置
        const validation = this.validateSkillConfig(processedSkill);
        if (!validation.valid) {
            throw new Error(`Skill validation failed: ${validation.errors.join(', ')}`);
        }
        
        return processedSkill;
    }

    /**
     * 应用模板
     */
    private async applyTemplate(skill: ModernSkill): Promise<ModernSkill> {
        // 如果技能没有指定模板，直接返回
        if (!skill.category || !this.configTemplates.has(skill.category)) {
            return skill;
        }

        const template = this.configTemplates.get(skill.category)!;
        
        // 合并模板和技能配置
        const merged: ModernSkill = {
            ...template,
            ...skill,
            // 特殊处理数组字段
            effects: skill.effects || template.effects || [],
            tags: [...(template.tags || []), ...(skill.tags || [])],
            prerequisites: [...(template.prerequisites || []), ...(skill.prerequisites || [])]
        };

        return merged;
    }

    /**
     * 设置默认值
     */
    private setDefaultValues(skill: ModernSkill): ModernSkill {
        return {
            ...skill,
            quality: skill.quality ?? 1,
            tags: skill.tags || [],
            prerequisites: skill.prerequisites || [],
            targeting: {
                targetCount: 1,
                targetType: 'enemy',
                selectionStrategy: 'manual',
                ...skill.targeting
            },
            cooldown: {
                baseCooldown: 0,
                cooldownType: 'turns',
                ...skill.cooldown
            }
        };
    }

    /**
     * 验证效果配置
     */
    private validateEffectConfig(effect: SkillEffectConfig, index: number): string[] {
        const errors: string[] = [];
        const prefix = `Effect ${index}:`;

        if (!effect.type) {
            errors.push(`${prefix} Missing effect type`);
        }

        if (typeof effect.power !== 'number') {
            errors.push(`${prefix} Missing or invalid power value`);
        }

        if (!effect.targetType) {
            errors.push(`${prefix} Missing target type`);
        }

        if (effect.probability !== undefined && (effect.probability < 0 || effect.probability > 1)) {
            errors.push(`${prefix} Invalid probability value (must be 0-1)`);
        }

        if (effect.duration !== undefined && effect.duration < 0) {
            errors.push(`${prefix} Invalid duration value (must be >= 0)`);
        }

        return errors;
    }
}
